package org.richin.io.image.util;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.ImageObserver;
import java.awt.image.Kernel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.swing.ImageIcon;

import com.sun.image.codec.jpeg.ImageFormatException;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/**
 * 图片缩放,缩略图,比列..
 * @author Administrator
 *
 */
public class ImageScale {
	/**
	 * 按指定像素大小缩放图像
	 *
	 * @param image
	 *            图像
	 * @param width
	 *            宽度像素
	 * @param heigth
	 *            高度像素
	 * @return 缩放后的图像
	 */
	public static BufferedImage zoom(BufferedImage image, int width, int heigth) {

		BufferedImage tag = new BufferedImage(width, heigth, BufferedImage.TYPE_INT_RGB);
		/*
		 * Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的 优先级比速度高 生成的图片质量比较好 但速度慢
		 */
		tag.getGraphics().drawImage(image.getScaledInstance(width, heigth, Image.SCALE_SMOOTH), 0, 0, null);
		return tag;
	}

	/**
	 * 按指定比例缩放图像
	 *
	 * @param image
	 *            原图像
	 * @param sx
	 *            x轴缩放比例
	 * @param sy
	 *            y轴缩放比例
	 * @return 缩放后的图像
	 */
	public static BufferedImage zoom(BufferedImage image, double s) {

		int width = (int) (image.getWidth() * s);
		int heigth = (int) (image.getHeight() * s);
		return zoom(image, width, heigth);
	}//ImageUtils.writeImage(zoom(ImageUtils.readImage(new File("c:/bb.jpg")),0.34),"jpg",new File("c:/tu.jpg"));一般般

	/** 
	  *   缩放图片 
	  *   @param   in   读入图片流 
	  *   @param   out   写出流 
	  *   @throws   ImageFormatException 
	  *   @throws   IOException 
	  */
	public static void Zoom(java.io.InputStream in, OutputStream out, int zoom) throws ImageFormatException,
			IOException {
		JPEGImageDecoder decoderFile = JPEGCodec.createJPEGDecoder(in);
		BufferedImage imageFile = decoderFile.decodeAsBufferedImage();

		//获得目标图片的宽高，同时乘以放缩比例得到新图片大小 
		int w = (int) (imageFile.getWidth() * zoom);
		int h = (int) (imageFile.getHeight() * zoom);
		//建立一个新图片的缓存图片 
		BufferedImage bufImage = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
		//从目标图片上获得Graphics以便画在新图片上，最后一个参数是内部无名类，可以用null代替 
		Graphics g = bufImage.getGraphics();
		g.drawImage(imageFile, 0, 0, w, h, new ImageObserver() {
			public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
				return true;
			}
		});
		//编码输出 
		JPEGImageEncoder jpeg = JPEGCodec.createJPEGEncoder(out);
		jpeg.encode(bufImage);
		out.flush();
		out.close();
		in.close();
	}

	/**
	 * 缩放图像
	 * @param originalFile 原图像
	 * @param resizedFile  目标文件
	 * @param newWidth 新宽度
	 * @param quality 品质
	 * @throws IOException
	 */
	public static void resize(File originalFile, File resizedFile, int newWidth, float quality) throws IOException {

		if (quality < 0 || quality > 1) {
			throw new IllegalArgumentException("Quality has to be between 0 and 1");
		}

		ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
		Image i = ii.getImage();
		Image resizedImage = null;

		int iWidth = i.getWidth(null);
		int iHeight = i.getHeight(null);

		if (iWidth > iHeight) {
			resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH);
		} else {
			resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH);
		}

		// This code ensures that all the pixels in the image are loaded.
		Image temp = new ImageIcon(resizedImage).getImage();

		// Create the buffered image.
		BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null),
				BufferedImage.TYPE_INT_RGB);

		// Copy image to buffered image.
		Graphics g = bufferedImage.createGraphics();

		// Clear background and paint the image.
		g.setColor(Color.white);
		g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
		g.drawImage(temp, 0, 0, null);
		g.dispose();

		// Soften.
		float softenFactor = 0.05f;
		float[] softenArray = { 0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0,
				softenFactor, 0 };
		Kernel kernel = new Kernel(3, 3, softenArray);
		ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
		bufferedImage = cOp.filter(bufferedImage, null);

		// Write the jpeg to a file.
		FileOutputStream out = new FileOutputStream(resizedFile);

		// Encodes image as a JPEG data stream
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

		JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bufferedImage);

		param.setQuality(quality, true);

		encoder.setJPEGEncodeParam(param);
		encoder.encode(bufferedImage);
	}

	/*    File originalImage = new File("c:/bb.jpg");
	resize(originalImage, new File("c:/cc21.jpg"), 350, 0.7f);
	resize(originalImage, new File("c:/cc13.jpg"), 350, 1f);
	压缩品质高
	*/
	public static void encodeJPEG(OutputStream outputStream, Image outputImage, float outputQuality)
			throws java.io.IOException {
		int outputWidth = outputImage.getWidth(null);
		if (outputWidth < 1)
			throw new IllegalArgumentException("output image width " + outputWidth + " is out of range");
		int outputHeight = outputImage.getHeight(null);
		if (outputHeight < 1)
			throw new IllegalArgumentException("output image height " + outputHeight + " is out of range");
		// Get a buffered image from the image.
		BufferedImage bi = new BufferedImage(outputWidth, outputHeight, BufferedImage.TYPE_INT_RGB);
		Graphics2D biContext = bi.createGraphics();
		biContext.drawImage(outputImage, 0, 0, null);
		// Additional drawing code, such as
		// watermarks or logos can be placed here.
		// com.sun.image.codec.jpeg package
		// is included in Sun and IBM sdk 1.3.
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(outputStream);
		// The default quality is 0.75.
		JPEGEncodeParam jep = JPEGCodec.getDefaultJPEGEncodeParam(bi);
		jep.setQuality(outputQuality, true);
		encoder.encode(bi, jep);
		outputStream.flush();
	} // encodeImage

	public static void main(String[] args) throws IOException {
		File originalImage = new File("c:/bb.jpg");

	}

}
